package com.lmx.persistence.service;

import java.math.BigInteger;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.lmx.common.constants.CommonConstants;
import com.lmx.common.constants.ICommonConstants;
import com.lmx.common.constants.LeaveStatus;
import com.lmx.common.context.ActionContextHolder;
import com.lmx.common.util.CommonUtil;
import com.lmx.common.util.GenerateQrCodeUtil;
import com.lmx.repoDomain.tmodel.Bed;
import com.lmx.repoDomain.tmodel.Customer;
import com.lmx.repoDomain.tmodel.CustomerBusinessFlow;
import com.lmx.repoDomain.tmodel.CustomerDevice;
import com.lmx.repoDomain.tmodel.CustomerDrugProject;
import com.lmx.repoDomain.tmodel.CustomerDrugProjectItem;
import com.lmx.repoDomain.tmodel.CustomerServerChange;
import com.lmx.repoDomain.tmodel.CustomerServiceItem;
import com.lmx.repoDomain.tmodel.Device;
import com.lmx.repoDomain.tmodel.Dicttype;
import com.lmx.repoDomain.tmodel.Employee;
import com.lmx.repoDomain.tmodel.EmployeeCustomer;
import com.lmx.repoDomain.tmodel.EvaluateModel;
import com.lmx.repoDomain.tmodel.LocationInfo;
import com.lmx.repoDomain.tmodel.NurseGroup;
import com.lmx.repoDomain.tmodel.NursingLevel;
import com.lmx.repoDomain.tmodel.NursingLevelServiceItem;
import com.lmx.repoDomain.tmodel.NursingPlanDetail;
import com.lmx.repoDomain.tmodel.NursingProject;
import com.lmx.repoDomain.tmodel.NursingProjectServiceItem;
import com.lmx.repoDomain.tmodel.PersonLocation;
import com.lmx.repoDomain.tmodel.RechargeRecord;
import com.lmx.repoDomain.tmodel.Role;
import com.lmx.repoDomain.tmodel.Room;
import com.lmx.repoDomain.tmodel.SpecService;
import com.lmx.repoDomain.tmodel.StaffCustomer;
import com.lmx.repoDomain.tmodel.Tenant;
import com.lmx.repoDomain.tmodel.TradeAccount;
import com.lmx.repoDomain.tmodel.business.User;

/**
 *
 *
 * @author huibati
 * @version 1.00
 */
@Service
@Scope("prototype")
public class CustomerService<T> {

	private Log logger = LogFactory.getLog(this.getClass());

	@PersistenceContext
	private EntityManager em;

	@Autowired
	protected GenericService dslJpaService;

	@Autowired
	protected CommonService commonService;

	@Autowired
	private WorkPlaceService workPlaceService;

	@Autowired
	private AccountService accountService;

	@Autowired
	private NursingService nursingService;

	@Autowired
	private WeiXinService weXinService;

	@Autowired
	private UserService<User> userService;

	@Autowired
	private RoleService<Role> roleService;

	@Autowired
	private DicttypeService dicttypeService;

	@Autowired
	private CustomerLeaveService customerLeaveService;

	/**
	 * 获取位置表中 员工的最新位置 弃用
	 */
	public Iterable<LocationInfo> getStaffLocationDataOld(Long tenantId,
			Long buildingId) {
		List dataList = new ArrayList<>();
		StringBuilder query = new StringBuilder(
				" select a from PersonLocation a "
						+ " where  not exists(select 1 "
						+ " from PersonLocation b "
						+ " where b.employee.id=a.employee.id and b.locationTime>a.locationTime"
						+ " and b.delStatus != ?1 and b.tenant.id=?2 and b.employee is not null and b.room is not null ) "
						+ " and a.delStatus != ?1 and a.tenant.id=?2 and a.employee is not null	and a.room is not null ");
		if (buildingId != -1) {
			query.append(" and a.room.floor.building.id=" + buildingId);
		}
		List<PersonLocation> locationList = this.em
				.createQuery(query.toString()).setParameter(1, (short) 1)
				.setParameter(2, tenantId).getResultList();
		long idTemp = 1;
		if (locationList != null && locationList.size() > 0) {
			for (PersonLocation pl : locationList) {
				LocationInfo ld = new LocationInfo();
				ld.setEmployee(pl.getEmployee());
				ld.setRoom(pl.getRoom());
				ld.setId(idTemp);
				ld.setTenant(pl.getEmployee().getTenant());
				dataList.add(ld);
				idTemp++;
			}
		}
		return dataList;
	}

	/**
	 * 获取位置表中 员工的最新位置
	 */
	public Iterable<LocationInfo> getStaffLocationData(Long tenantId,
			Long buildingId) {
		List dataList = new ArrayList<>();
		Iterator it;
		List<Long> employeeIdList = new ArrayList<>();
		List<Long> roomIdList = new ArrayList<>();
		Map<String, Employee> employeeMap = new HashMap<>();
		Map<String, Room> roomMap = new HashMap<>();
		Tenant tenant = new Tenant();
		long idTemp = 1;
		StringBuilder query = new StringBuilder(
				" SELECT t.employee_id,t.room_id ,t.tenant_id FROM "
						+ " ( SELECT personloca1_.* FROM tnb_person_location personloca1_,tnb_room r,tnb_floor f,tnb_building b "
						+ " WHERE    personloca1_.del_status<>?1 "
						+ " And personloca1_.tenant_id = ?2 "
						+ " AND personloca1_.employee_id IS NOT NULL "
						+ " AND personloca1_.room_id IS NOT NULL ");
		if (buildingId != -1) {
			query.append("and r.id=personloca1_.room_id "
					+ " and r.floor_id=f.id " + " and f.building_id = b.id "
					+ " AND b.id =" + buildingId);
		}
		query.append(" ORDER BY	personloca1_.createDateTime DESC ) t GROUP BY t.employee_id, t.tenant_id ");
		String lpSql = query.toString();
		if (buildingId == -1) {
			lpSql.replaceAll(",tnb_room r,tnb_floor f,tnb_building b", "");
		}
		List locationList = this.em.createNativeQuery(lpSql)
				.setParameter(1, (short) 1).setParameter(2, tenantId)
				.getResultList();
		it = locationList.iterator();
		while (it.hasNext()) {
			Object[] res = (Object[]) it.next();
			employeeIdList.add(((BigInteger) res[0]).longValue());
			roomIdList.add(((BigInteger) res[1]).longValue());
			tenant.setId(((BigInteger) res[2]).longValue());
		}
		// 建立员工以及房间map
		if (employeeIdList.size() > 0) {
			StringBuilder cSql = new StringBuilder(
					"select c from Employee c  where c.id in(:staffs) ");
			List<Employee> employeeList = this.em.createQuery(cSql.toString())
					.setParameter("staffs", employeeIdList).getResultList();
			if (employeeList != null && employeeList.size() > 0) {
				for (Employee staff : employeeList) {
					employeeMap.put(staff.getId().toString(), staff);
				}
			}
		}
		if (roomIdList.size() > 0) {
			StringBuilder rSql = new StringBuilder(
					"select c from Room c  where c.id in(:rooms) ");
			List<Room> roomList = this.em.createQuery(rSql.toString())
					.setParameter("rooms", roomIdList).getResultList();
			if (roomList != null && roomList.size() > 0) {
				for (Room room : roomList) {
					roomMap.put(room.getId().toString(), room);
				}
			}
		}
		if (roomIdList.size() > 0 && employeeIdList.size() > 0) {
			it = locationList.iterator();
			while (it.hasNext()) {
				Object[] res = (Object[]) it.next();
				LocationInfo ld = new LocationInfo();
				ld.setEmployee(employeeMap.get(((BigInteger) res[0]).toString()));
				ld.setRoom(roomMap.get(((BigInteger) res[1]).toString()));
				ld.setTenant(tenant);
				ld.setId(idTemp);
				dataList.add(ld);
				idTemp++;
			}
		}
		return dataList;
	}

	/**
	 * 获取位置表中 老人的最新位置
	 */
	public Iterable<LocationInfo> getCustomerLocationData(Long tenantId,
			Long buildingId) {
		List dataList = new ArrayList<>();
		Iterator it;
		List<Long> customerIdList = new ArrayList<>();
		List<Long> roomIdList = new ArrayList<>();
		Map<String, Customer> customerMap = new HashMap<>();
		Map<String, Room> roomMap = new HashMap<>();
		Tenant tenant = new Tenant();
		long idTemp = 1;
		String curTime = CommonUtil.getCurrTimeForString();// 当日日期
		Integer curTimeStart = 0;
		Integer curTimeEnd = 0;
		try {
			curTimeStart = CommonUtil.strToIntegerTime(curTime.substring(0, 10)
					+ " 00:00:00");
			curTimeEnd = CommonUtil.strToIntegerTime(curTime.substring(0, 10)
					+ " 23:59:59");
		} catch (ParseException e) {
			logger.error("timer error " + e);
		}
		StringBuilder query = new StringBuilder(
				" SELECT t.customer_id,t.room_id ,t.tenant_id FROM "
						+ " ( SELECT personloca1_.* FROM tnb_person_location personloca1_,tnb_room r,tnb_floor f,tnb_building b "
						+ " WHERE    personloca1_.del_status<>?1 "
						+ " And personloca1_.tenant_id = ?2 "
						+ " AND personloca1_.customer_id IS NOT NULL "
						+ " AND personloca1_.room_id IS NOT NULL "
						+ " and personloca1_.location_time>=?3 and personloca1_.location_time<=?4 ");
		if (buildingId != -1) {
			query.append("and r.id=personloca1_.room_id "
					+ " and r.floor_id=f.id " + " and f.building_id = b.id "
					+ " AND b.id =" + buildingId);
		}
		query.append(" ORDER BY	personloca1_.createDateTime DESC ) t GROUP BY t.customer_id, t.tenant_id ");
		String lpSql = query.toString();
		if (buildingId == -1) {
			lpSql.replaceAll(",tnb_room r,tnb_floor f,tnb_building b", "");
		}
		List locationList = this.em.createNativeQuery(lpSql)
				.setParameter(1, (short) 1).setParameter(2, tenantId)
				.setParameter(3, curTimeStart).setParameter(4, curTimeEnd)
				.getResultList();
		it = locationList.iterator();
		while (it.hasNext()) {
			Object[] res = (Object[]) it.next();
			customerIdList.add(((BigInteger) res[0]).longValue());
			roomIdList.add(((BigInteger) res[1]).longValue());
			tenant.setId(((BigInteger) res[2]).longValue());
		}
		// 建立老人以及房间map
		if (customerIdList.size() > 0) {
			StringBuilder cSql = new StringBuilder(
					"select c from Customer c  where c.id in(:olds) ");
			List<Customer> customerList = this.em.createQuery(cSql.toString())
					.setParameter("olds", customerIdList).getResultList();
			if (customerList != null && customerList.size() > 0) {
				for (Customer old : customerList) {
					customerMap.put(old.getId().toString(), old);
				}
			}
		}
		if (roomIdList.size() > 0) {
			StringBuilder rSql = new StringBuilder(
					"select c from Room c  where c.id in(:rooms) ");
			List<Room> roomList = this.em.createQuery(rSql.toString())
					.setParameter("rooms", roomIdList).getResultList();
			if (roomList != null && roomList.size() > 0) {
				for (Room room : roomList) {
					roomMap.put(room.getId().toString(), room);
				}
			}
		}
		if (roomIdList.size() > 0 && customerIdList.size() > 0) {
			it = locationList.iterator();
			while (it.hasNext()) {
				Object[] res = (Object[]) it.next();
				LocationInfo ld = new LocationInfo();
				ld.setCustomer(customerMap.get(((BigInteger) res[0]).toString()));
				ld.setRoom(roomMap.get(((BigInteger) res[1]).toString()));
				ld.setTenant(tenant);
				ld.setId(idTemp);
				dataList.add(ld);
				idTemp++;
			}
		}
		return dataList;
	}

	/**
	 * 获取没有护理方案的客户
	 */
	public Iterable<Customer> getCustomerListFilterProject() {
		StringBuilder query = new StringBuilder(
				"select c from Customer c where c.delStatus != ?1 and c.tenant.id=?2 and "
						+ "c not in ( select p.customer from NursingProject p where p.delStatus != ?1 and p.tenant.id=?2 )  ");
		List dataList = this.em
				.createQuery(query.toString())
				.setParameter(1, (short) 1)
				.setParameter(2, ActionContextHolder.getContext().getTenantId())
				.getResultList();
		return dataList;
	}

	/**
	 * 获取有药品的客户
	 */
	public Iterable<Customer> getCustomerListFilterDrugs() {
		StringBuilder query = new StringBuilder(
				"select distinct c.customer from CustomerDrug c where c.delStatus != ?1 and  c.tenant.id=?2 ");
		List dataList = this.em
				.createQuery(query.toString())
				.setParameter(1, (short) 1)
				.setParameter(2, ActionContextHolder.getContext().getTenantId())
				.getResultList();
		return dataList;
	}

	/**
	 * 获取
	 */
	public Customer getCustomer(Customer customer) {
		StringBuilder query = new StringBuilder(
				"select c from Customer c where c.id= ?1");
		Long id = customer.getId();
		Customer ct = (Customer) this.em.createQuery(query.toString())
				.setParameter(1, id).getSingleResult();
		return ct;
	}

	/**
	 * 获取
	 */
	public Customer getCustomerWithBed(long bedId) {

		StringBuilder query = new StringBuilder(
				"select c from Customer c where c.bed.id= ?1 and c.delStatus!=1");
		List dataList = this.em.createQuery(query.toString())
				.setParameter(1, bedId).getResultList();
		Customer ct = null;
		if (dataList.size() > 0) {
			ct = (Customer) dataList.get(0);
		}
		return ct;
	}

	/**
	 * 获取
	 */
	public Customer getCustomerByEtcommID(String etcommID, String etcommID2) {
		StringBuilder query = new StringBuilder(
				"select c from Customer c where c.etcommID = ?1 or c.etcommID = ?2");
		List dataList = this.em.createQuery(query.toString())
				.setParameter(1, etcommID).setParameter(2, etcommID2)
				.getResultList();
		Customer ct = null;
		if (dataList.size() > 0) {
			ct = (Customer) dataList.get(0);
		}
		return ct;
	}

	/**
	 * 产生customer所对应的账户
	 */
	public TradeAccount createAccount(Customer customer, Dicttype accountType,
			Double balance) {
		TradeAccount account = new TradeAccount();
		account.setCustomer(customer);
		account.setType(accountType);
		// 初始化其它org信息 huibati
		account.setBalance(balance);
		account.setTenant(customer.getTenant());
		account.setDelStatus((short) 0);
		dslJpaService.setEntityClass(TradeAccount.class);
		account = (TradeAccount) dslJpaService.create(account);
		return account;
	}

	// 获取CustomerBusinessFlow
	public CustomerBusinessFlow getCustomerBusinessFlow(
			CustomerBusinessFlow record) {
		Long id = record.getId();
		CustomerBusinessFlow ct = (CustomerBusinessFlow) this.em
				.createQuery(
						"select c from CustomerBusinessFlow c where c.id = ?1")
				.setParameter(1, id).getSingleResult();
		return ct;
	}

	// 获取CustomerBusinessFlow
	public CustomerBusinessFlow getCustomerBusinessFlow(Customer customer) {
		Long id = customer.getId();
		CustomerBusinessFlow ct = (CustomerBusinessFlow) this.em
				.createQuery(
						"select c from CustomerBusinessFlow c where c.customer.id = ?1 and c.delStatus!=1 and ( c.status.typecode =?2 or c.status.typecode =?3 or c.status.typecode =?4 ) ")
				.setParameter(1, id).setParameter(2, "consultStatus3")
				.setParameter(3, "consultStatus4")
				.setParameter(4, "consultStatus5").getSingleResult();
		return ct;
	}

	/**
	 * @author huibati
	 * @param yesFlag
	 *            1:昨天为退住日期 0:今天为退住日期 操作退住审核通过 2017年6月26日
	 */
	@Transactional
	public void operateCustomerBack(CustomerBusinessFlow record,
			Customer customer, int yesFlag) {
		// 修改客户状态 床位状态 退住flow记录状态 生成日账单 月账单
		// 删除护理方案项,护理计划,护理计划模版,用药计划,评估问卷以及入住的flow
		Bed bedOld = null;
		bedOld = customer.getBed();
		Dicttype bedIdle = commonService
				.getDicttype(CommonConstants.DICTTYPE.BED_STATUS_1.label());// 空闲
		Dicttype billCreated = commonService
				.getDicttype(CommonConstants.DICTTYPE.FLOW_LEAVE_STATUS_2
						.label());// 账单生成
		Dicttype backBed = commonService.getDicttype("customerStatusOut");// 已退住
		// 解绑设备
		List<Device> deviceList = this.getCustomerDevices(customer);
		if (deviceList != null && deviceList.size() > 0) {
			Dicttype deviceIdle = commonService
					.getDicttype(CommonConstants.DICTTYPE.DEVICE_STATUS_1
							.label());// 设备空闲
			for (Device device : deviceList) {
				device.setStatus(deviceIdle);
				device.setBindStatus(commonService
						.getDicttype(CommonConstants.DICTTYPE.DEVICE_BIND_STATUS_2
								.label()));
				device.setLastUpdateDateTime(CommonUtil.getCurrTimes());
			}
			commonService.batchUpdate(deviceList); // 解绑设备 设为空闲
		}
		// 修改设备相关信息
		StringBuilder query = new StringBuilder(
				" update CustomerDevice u set u.delStatus = ?1 , u.lastUpdateDateTime = ?2 where u.customer.id = ?3 ");
		this.em.createQuery(query.toString()).setParameter(1, (short) 1)
				.setParameter(2, CommonUtil.getCurrTimes())
				.setParameter(3, customer.getId()).executeUpdate();
		// 更改床位状态
		workPlaceService.changeDedStauts(bedOld, bedIdle);
		// 删除 护理方案 project
		query.delete(0, query.length());
		query.append(" update NursingProject u set u.delStatus = ?1 , u.lastUpdateDateTime = ?2 where u.customer.id = ?3 ");
		this.em.createQuery(query.toString()).setParameter(1, (short) 1)
				.setParameter(2, CommonUtil.getCurrTimes())
				.setParameter(3, customer.getId()).executeUpdate();
		// 删除 护理方案项 projectitem
		query.delete(0, query.length());
		query.append(" select u from NursingProjectServiceItem u  where  u.delStatus != 1 and u.project.customer.id = ?1 ");
		List<NursingProjectServiceItem> npsItemList = this.em
				.createQuery(query.toString())
				.setParameter(1, customer.getId()).getResultList();
		if (npsItemList != null && npsItemList.size() > 0) {
			query.delete(0, query.length());
			query.append(" update NursingProjectServiceItem u set u.delStatus = ?1   where u in (:items) ");
			this.em.createQuery(query.toString()).setParameter(1, (short) 1)
					.setParameter("items", npsItemList).executeUpdate();
		}
		// 删除护理计划NursingPlanDetail
		query.delete(0, query.length());
		query.append(" update NursingPlanDetail u set u.delStatus = ?1 , u.lastUpdateDateTime = ?2 where u.customer.id = ?3 ");
		this.em.createQuery(query.toString()).setParameter(1, (short) 1)
				.setParameter(2, CommonUtil.getCurrTimes())
				.setParameter(3, customer.getId()).executeUpdate();
		// 删除 护理计划模版NursingPlanServiceItem
		query.delete(0, query.length());
		query.append(" update NursingPlanServiceItem u set u.delStatus = ?1  where u.customer.id = ?3 ");
		this.em.createQuery(query.toString()).setParameter(1, (short) 1)// 已删除
				.setParameter(3, customer.getId()).executeUpdate();
		// 删除 用药计划，评估问卷以及入住的flow
		query.delete(0, query.length());
		query.append(" update EvaluateResult u set u.delStatus = ?1 , u.lastUpdateDateTime = ?2 where u.customer.id = ?3 ");
		this.em.createQuery(query.toString()).setParameter(1, (short) 1)
				.setParameter(2, CommonUtil.getCurrTimes())
				.setParameter(3, customer.getId()).executeUpdate();
		// 删除 入住的flow
		query.delete(0, query.length());
		query.append(" update CustomerBusinessFlow u set u.delStatus = ?1 , u.lastUpdateDateTime = ?2 where u.customer.id = ?3 and u.backRemark='in' ");
		this.em.createQuery(query.toString()).setParameter(1, (short) 1)
				.setParameter(2, CommonUtil.getCurrTimes())
				.setParameter(3, customer.getId()).executeUpdate();
		// 删除 用药 huibati
		query.delete(0, query.length());
		query.append(" update CustomerDrug u set u.delStatus = ?1 , u.lastUpdateDateTime = ?2 where u.customer.id = ?3 ");
		this.em.createQuery(query.toString()).setParameter(1, (short) 1)
				.setParameter(2, CommonUtil.getCurrTimes())
				.setParameter(3, customer.getId()).executeUpdate();
		query.delete(0, query.length());
		query.append(" select u from  CustomerDrugProject u  where  u.delStatus != 1 and u.customerDrug.customer.id = ?1 ");
		List<CustomerDrugProject> cdpList = this.em
				.createQuery(query.toString())
				.setParameter(1, customer.getId()).getResultList();
		if (cdpList != null && cdpList.size() > 0) {
			query.delete(0, query.length());
			query.append(" update CustomerDrugProject u set u.delStatus = ?1 , u.lastUpdateDateTime = ?2 where u in (:items) ");
			this.em.createQuery(query.toString()).setParameter(1, (short) 1)
					.setParameter(2, CommonUtil.getCurrTimes())
					.setParameter("items", cdpList).executeUpdate();
		}
		// 更改客户状态
		customer.setBed(null);
		changeCustomerStauts(customer, backBed);
		// 更改flow记录状态
		if (record != null) {
			record.setLeaveStatus(billCreated);
			record.setRemark(bedOld.getRoom().getFloor().getBuilding().getName()+"-"+bedOld.getRoom().getFloor().getName()+"-"+bedOld.getRoom().getName()+"-"+bedOld.getName());
			dslJpaService.setEntityClass(CustomerBusinessFlow.class);
			dslJpaService.update(record);
			// 生成单日账单
			if (yesFlag != 1) {
				accountService.createDayBill(record.getCustomer(),
						CommonUtil.getCurrTimeForString());// 生成当日日账单
			}
			// 生成当月账单
			try {
				Integer startTime = CommonUtil.strToIntegerTime(CommonUtil
						.getMonthFirstDayForString().substring(0, 10)
						+ " 00:00:00");
				String lastDay = CommonUtil.getMonthLastDayForString()
						.substring(0, 10);
				Integer endTime = CommonUtil.strToIntegerTime(lastDay
						+ " 23:59:59");
				accountService.createCustomerBill(record.getCustomer(),
						startTime, endTime, null);// 生成当月账单
			} catch (Exception e) {
				logger.debug("operateCustomerBack error :" + e);
			}
		}
	}

	// 客户直接 预定 试住 入住 更改床位状态 客户状态 产生变更记录
	@Transactional
	public void directCreateBusinessFlow(CustomerBusinessFlow record) {
		// 根据flow生成customer
		Customer customer = new Customer();
		customer = this.copyCusomerDataFromBusinessFlow(record, customer);
		// 更改床位以及客户状态
		if ("consultStatus3".equals(record.getStatus().getTypecode())
				&& record.getOrderBed() != null) { // 预定
			Dicttype bedAppointment = commonService
					.getDicttype(CommonConstants.DICTTYPE.BED_STATUS_4.label());
			workPlaceService.changeDedStauts(record.getOrderBed(),
					bedAppointment);
			customer.setBed(record.getOrderBed());
			customer.setCheckInDate(record.getOrderInTime());
			customer.setCustomerStatus(commonService
					.getDicttype("customerStatus0"));
		}
		if ("consultStatus4".equals(record.getStatus().getTypecode())
				&& record.getCheckInBed() != null) { // 直接试住
			Dicttype bedTry = commonService
					.getDicttype(CommonConstants.DICTTYPE.BED_STATUS_3.label());
			workPlaceService.changeDedStauts(record.getCheckInBed(), bedTry);
			customer.setCustomerStatus(commonService
					.getDicttype("customerStatusTry"));
		}
		if ("consultStatus5".equals(record.getStatus().getTypecode())
				&& record.getCheckInBed() != null) { // 直接入住
			Dicttype bedIn = commonService
					.getDicttype(CommonConstants.DICTTYPE.BED_STATUS_2.label());
			workPlaceService.changeDedStauts(record.getCheckInBed(), bedIn);
			customer.setCustomerStatus(commonService
					.getDicttype("customerStatusIn"));
		}
		// 创建customer
		customer = this.createCustomer(customer);
		record.setCustomer(customer);
		// 直接试住 入住生成变更记录
		if ("consultStatus4".equals(record.getStatus().getTypecode())
				|| "consultStatus5".equals(record.getStatus().getTypecode())) {
			this.createCustomerServerChangeByBusiFlow(null, record);// 生成服务变更记录--直接入住
																	// 直接试住
		}
		// 生成二维码 生成 电子金额以及保证金账户 充值记录
		this.operateCreateCustomer(customer);
		// 入住 试住 生成护理方案
		if ("consultStatus5".equals(record.getStatus().getTypecode())
				|| "consultStatus4".equals(record.getStatus().getTypecode())) {
			this.createCustomerProjectByNursingLevel(customer,
					record.getNursinglevel(), record.getLevelPrice());
		}
	}

	// 验证Customer是否有Project
	public int checkCustomerWithProject(Customer customer) {
		List<NursingProject> cList = new ArrayList<>();
		cList = this.em
				.createQuery(
						"select c from NursingProject c where c.delStatus!=1 and c.customer.id =?1  ")
				.setParameter(1, customer.getId()).getResultList();
		return cList.size();
	}

	// 客户更改入住状态 预定-试住 预定-入住 试住-入住
	@Transactional
	public void businessFlowStatusChanged(CustomerBusinessFlow ctTemp,
			CustomerBusinessFlow record) {
		// CustomerBusinessFlow ctTemp = getCustomerBusinessFlow(record);
		Customer customer = record.getCustomer();
		Bed bedNew = null;
		Bed bedOld = null;
		bedOld = customer.getBed();
		Dicttype bedIdle = commonService
				.getDicttype(CommonConstants.DICTTYPE.BED_STATUS_1.label());
		Dicttype bedIn = commonService
				.getDicttype(CommonConstants.DICTTYPE.BED_STATUS_2.label());
		Dicttype bedTryIn = commonService
				.getDicttype(CommonConstants.DICTTYPE.BED_STATUS_3.label());
		String sratTime = CommonUtil.integetTimeForString(
				record.getCheckInDate()).substring(0, 10);// 住宿开始时间
		String now = CommonUtil.getCurrTimeForString().substring(0, 10)
				.substring(0, 10);
		int projectFlag = this.checkCustomerWithProject(customer);// 验证当前Customer是否已经生成Project
		// 试住
		if ("consultStatus4".equals(record.getStatus().getTypecode())) {
			// 床位为更改就不判断 更改的话验证 新床是否占用
			bedNew = record.getCheckInBed();// 试住床位
			// 验证如果生效日期是今天 床位发生变化 将床位置为空闲
			if (sratTime.equals(now)
					&& ctTemp.getOrderBed() != null
					&& !ctTemp.getOrderBed().getId()
							.equals(record.getCheckInBed().getId())) {
				workPlaceService.changeDedStauts(ctTemp.getOrderBed(), bedIdle);
			}
			// 更改新的床位状态
			workPlaceService.changeDedStauts(bedNew, bedTryIn);
			if (record.getBedPrice() != null) {
				customer.setActualBedPrice(record.getBedPrice().toString());
			}
			if (record.getDiningStandardPrice() != null) {
				customer.setActualDiningPrice(record.getDiningStandardPrice()
						.toString());
			}
			customer = this.copyCusomerDataFromBusinessFlow(record, customer);
			customer.setCustomerStatus(commonService
					.getDicttype("customerStatusTry"));// 老人状态
			customer.setContractNO(record.getInContractNO());// 合同编号
			customer.setCardCode(record.getCustomerCardCode());
			customer.setContractStartDate(Integer.parseInt(record
					.getCheckInStartTime().toString()));// 合同日期
			customer.setContractEndDate(Integer.parseInt(record
					.getCheckInEndTime().toString()));// 设置合同编号开始结束日期
			customer.setExperienceStartDate(record.getCheckInStartTime()
					.toString());
			customer.setExperienceEndDate(record.getCheckInEndTime().toString());
			customer.setCheckInDate(Integer.parseInt(record
					.getCheckInStartTime().toString())); // 入住日期
			if (customer.getQrCodeUrl() == null
					|| "".equals(customer.getQrCodeUrl())) {
				customer.setQrCodeUrl(GenerateQrCodeUtil
						.generateQrcode("tnbId:" + customer.getId().toString())); // 生成客户ID微信二维码
			}
			// 更改老人信息
			dslJpaService.setEntityClass(Customer.class);
			dslJpaService.update(customer);
			if (projectFlag > 0) {

			} else {
				// 预定转试住 生成护理方案
				if (record.getNursinglevel() != null) {
					this.createCustomerProjectByNursingLevel(customer,
							record.getNursinglevel(), null);
				}
			}
		}
		// 入住
		if ("consultStatus5".equals(record.getStatus().getTypecode())) {
			bedNew = record.getCheckInBed();
			// 验证如果生效日期是今天 床位发生变化 将床位置为空闲
			if (("consultStatus3".equals(ctTemp.getStatus().getTypecode()))) {
				if (sratTime.equals(now)
						&& ctTemp.getOrderBed() != null
						&& !ctTemp.getOrderBed().getId()
								.equals(record.getCheckInBed().getId())) {
					workPlaceService.changeDedStauts(ctTemp.getOrderBed(),
							bedIdle);
				}
				customer = this.copyCusomerDataFromBusinessFlow(record,
						customer);
			}
			if (("consultStatus4".equals(ctTemp.getStatus().getTypecode()))) {
				if (sratTime.equals(now)
						&& ctTemp.getCheckInBed() != null
						&& !ctTemp.getCheckInBed().getId()
								.equals(record.getCheckInBed().getId())) {
					workPlaceService.changeDedStauts(ctTemp.getCheckInBed(),
							bedIdle);
				}
			}
			// 更改床位状态
			workPlaceService.changeDedStauts(bedNew, bedIn);
			customer.setCustomerStatus(commonService
					.getDicttype("customerStatusIn"));// 老人状态
			customer.setContractNO(record.getInContractNO());// 合同编号
			customer.setCardCode(record.getCustomerCardCode());
			customer.setContractStartDate(Integer.parseInt(record
					.getCheckInStartTime().toString()));
			customer.setContractEndDate(Integer.parseInt(record
					.getCheckInEndTime().toString()));// 设置合同编号开始结束日期
			customer.setCheckInDate(Integer.parseInt(record
					.getCheckInStartTime().toString()));// 入住日期
			// customer.setExperienceStartDate(record.getCheckInEndTime().toString());
			if (customer.getQrCodeUrl() == null
					|| "".equals(customer.getQrCodeUrl())) {
				customer.setQrCodeUrl(GenerateQrCodeUtil
						.generateQrcode("tnbId:" + customer.getId().toString())); // 生成客户ID微信二维码
			}
			// 更改老人信息
			dslJpaService.setEntityClass(Customer.class);
			dslJpaService.update(customer);
			if (("consultStatus3".equals(ctTemp.getStatus().getTypecode()))) {
				if (projectFlag > 0) {

				} else {
					// 预定转入住 生成护理方案
					if (record.getNursinglevel() != null) {
						this.createCustomerProjectByNursingLevel(customer,
								record.getNursinglevel(), null);
					}
				}
			}
		}
		// 生成服务变更记录
		if (("consultStatus3".equals(ctTemp.getStatus().getTypecode()) && "consultStatus4"
				.equals(record.getStatus().getTypecode())) || // 预定转试住
				("consultStatus3".equals(ctTemp.getStatus().getTypecode()) && "consultStatus5"
						.equals(record.getStatus().getTypecode())) || // 预定转入住
				("consultStatus4".equals(ctTemp.getStatus().getTypecode()) && "consultStatus5"
						.equals(record.getStatus().getTypecode())) // 试住转入住
		) {
			createCustomerServerChangeByBusiFlow(ctTemp, record); // 生成服务变更记录
		}
	}

	// 生成服务变更记录
	public void createCustomerServerChangeByBusiFlow(
			CustomerBusinessFlow oldRecord, CustomerBusinessFlow record) {
		CustomerServerChange temp = new CustomerServerChange();
		temp.setCustomer(record.getCustomer());
		if ((oldRecord != null && oldRecord.getCheckInPrice() != null && !""
				.equals(oldRecord.getCheckInPrice()))
				&& record.getCustomer().getActualPrice() != null
				&& !"".equals(record.getCustomer().getActualPrice())) {
			temp.setPriceOld(Double.parseDouble(record.getCustomer()
					.getActualPrice()));

		}
		temp.setDelStatus((short) 0);
		// 设置更改前后床位信息 价格
		if ("consultStatus4".equals(record.getStatus().getTypecode())) {// 预定转试住或直接试住
			temp.setEffectiveTime(record.getCheckInStartTime());// 试住
			temp.setPriceNew(Double.parseDouble(record.getCheckInPrice()));// 试住价格
			temp.setBedNew(record.getCheckInBed());// 试住床位
			if (oldRecord != null && oldRecord.getOrderBed() != null) {
				temp.setBedOld(oldRecord.getOrderBed());
			}
		}
		if ("consultStatus5".equals(record.getStatus().getTypecode())) {// 预定/试住转入住或直接入住
			temp.setEffectiveTime(record.getCheckInStartTime());
			temp.setPriceNew(Double.parseDouble(record.getCheckInPrice()));// 入住价格
			temp.setBedNew(record.getCheckInBed());
			if (oldRecord != null
					&& "consultStatus4".equals(oldRecord.getStatus()
							.getTypecode())) { // 试住
				if (oldRecord != null && oldRecord.getCheckInBed() != null) {
					temp.setBedOld(oldRecord.getCheckInBed());
				}
			}
			if (oldRecord != null
					&& "consultStatus3".equals(oldRecord.getStatus()
							.getTypecode())) { // 预定
				if (oldRecord.getOrderBed() != null) {
					temp.setBedOld(oldRecord.getOrderBed());
				}
			}
		}
		if (oldRecord != null && oldRecord.getDiningStandard() != null) {
			temp.setFoodLevelOld(oldRecord.getDiningStandard());
		}
		temp.setFoodLevelNew(record.getDiningStandard());
		if (oldRecord != null && oldRecord.getBedPrice() != null) {
			temp.setBedPriceOld(oldRecord.getBedPrice());
		}
		if (record.getBedPrice() != null) {
			temp.setBedPriceNew(record.getBedPrice());
		}

		if (oldRecord != null && oldRecord.getDiningStandardPrice() != null) {
			temp.setFoodPriceOld(oldRecord.getDiningStandardPrice());
		}
		if (record.getDiningStandardPrice() != null) {
			temp.setFoodPriceNew(record.getDiningStandardPrice());
		}
		if (oldRecord != null && oldRecord.getLevelPrice() != null) {
			temp.setProjectPriceOld(oldRecord.getLevelPrice());
		}
		if (record.getLevelPrice() != null) {
			temp.setProjectPriceNew(record.getLevelPrice());
		}
		temp.setStatus(commonService.getDicttype("applyStatus1"));
		dslJpaService.setEntityClass(CustomerServerChange.class);
		dslJpaService.create(temp);
	}

	// 处理服务变更请求
	@Transactional
	public void operateCustomerServerChange(CustomerServerChange record) {
		Customer customer = getCustomer(record.getCustomer());
		// 更新服务变更信息
		record.setStatus(commonService.getDicttype("applyStatus2"));
		if (customer.getActualPrice() != null
				&& !"".equals(customer.getActualPrice())) {
			record.setPriceOld(Double.parseDouble(customer.getActualPrice()));
		}
		dslJpaService.setEntityClass(CustomerServerChange.class);
		dslJpaService.update(record);
		// 更新客户相关信息
		customer.setActualPrice(record.getPriceNew().toString());
		if (record.getFoodLevelNew() != null) {
			customer.setDiningStandard(record.getFoodLevelNew());
		}
		if (record.getFoodPriceNew() != null) {
			customer.setActualDiningPrice(record.getFoodPriceNew().toString());
		}
		if (record.getBedNew() != null) {
			customer.setBed(record.getBedNew());
		}
		if (record.getBedPriceNew() != null) {
			customer.setActualBedPrice(record.getBedPriceNew().toString());
		}
		if (record.getProjectPriceNew() != null) {
			NursingProject project = nursingService
					.getProjectByCustomer(customer);
			if (project != null) {
				project.setPrice(record.getProjectPriceNew());
				dslJpaService.setEntityClass(NursingProject.class);
				dslJpaService.update(project);
			}
		}
		customer.setApplyFlag(0);
		dslJpaService.setEntityClass(Customer.class);
		dslJpaService.update(customer);
		// 更改床位信息 新床位改为入住 如果两个床位不一致需要将老床位置为空闲
		if (record.getBedNew() == null) {// 不修改床位

		} else {
			// 将新的床位设置为已入住
			workPlaceService
					.changeDedStauts(record.getBedNew(), commonService
							.getDicttype(CommonConstants.DICTTYPE.BED_STATUS_2
									.label()));
			if (record.getBedOld() != null
					&& !record.getBedOld().getId()
							.equals(record.getBedNew().getId())) {
				// 将原有床位设置为空闲
				workPlaceService
						.changeDedStauts(
								record.getBedOld(),
								commonService
										.getDicttype(CommonConstants.DICTTYPE.BED_STATUS_1
												.label()));
				// 将flow中checkInbed设置为新床位
				CustomerBusinessFlow flow = getCustomerBusinessFlow(customer);
				if (flow != null) {
					flow.setCheckInBed(record.getBedNew());
					dslJpaService.setEntityClass(CustomerBusinessFlow.class);
					dslJpaService.update(flow);
				}
			}
		}

	}

	// 建立Employee与customer 关系 弃用
	@Transactional
	public void buildEmployeeToCustomerByGroup(NurseGroup group) {
		// 建立Employee与customer 关系
		List<Employee> staffList = this.em
				.createQuery(
						"select c.employee from EmployeeNursingGroup c where c.group.id =?1  ")
				.setParameter(1, group.getId()).getResultList();

		if (group.getBeds() == null && staffList == null) {
			if (group.getBeds().size() == 0 || staffList.size() == 0) {

			} else {
				// 床位所对应老人
				List<Customer> customerList = this.em
						.createQuery(
								"select c from Customer c where c.bed in (:beds )  ")
						.setParameter("beds", group.getBeds()).getResultList();

				// 删除原有数据
				String query = "delete from EmployeeCustomer ec where ec.customer in (:olds) or ec.employee in (:staffs) ";
				this.em.createQuery(query).setParameter("olds", customerList)
						.setParameter("staffs", group.getStaffs())
						.executeUpdate();

				// persist 批量插入
				List<EmployeeCustomer> dataList = new ArrayList<>();
				for (int i = 0; i < staffList.size(); i++) {
					for (int j = 0; j < customerList.size(); j++) {
						if (group.getStaffs().get(i) != null
								&& customerList.get(j) != null) {
							EmployeeCustomer ec = new EmployeeCustomer();
							ec.setCustomer(customerList.get(j));
							ec.setEmployee(staffList.get(i));
							dataList.add(ec);
						}
					}
				}
				if (dataList.size() > 0) {
					commonService.batchInsert(dataList);
				}
			}
		}
	}

	/**
	 * 获取customerDrugProject Employee--group--bed---customer
	 */
	public Iterable<CustomerDrugProject> getCustomerDrugProjectByUID(long uid) {
		StringBuilder query = new StringBuilder(
				"select  c  from CustomerDrugProject c   where c.delStatus != ?1  "
						+ " and c.customerDrug.customer.customerStatus is not null and c.customerDrug.customer.customerStatus.typecode!=?3 "
						+ " and c.customerDrug.customer.bed in ( select b from Bed b where b.delStatus != ?1 "
						+ " and b in( select n.bed from BedNurseGroup n where n.delStatus != ?1 "
						+ " and n.group in( select c.group from EmployeeNursingGroup c where c.employee in (select u.employee from User u where u.id = ?2 )) "
						+ ")  ) ");
		List dataList = this.em.createQuery(query.toString())
				.setParameter(1, (short) 1).setParameter(2, uid)
				.setParameter(3, "customerStatusOut").getResultList();
		return dataList;
	}

	/**
	 * 获取customerDrugProject customer
	 */
	public Iterable<CustomerDrugProject> getCustomerDrugProjectByCID(long cid) {
		StringBuilder query = new StringBuilder(
				"select  c  from CustomerDrugProject c   where c.delStatus != ?1  "
						+ " and c.customerDrug.customer.customerStatus is not null and c.customerDrug.customer.customerStatus.typecode!=?3 "
						+ " and c.customerDrug.customer.id =?2 ) ");
		List dataList = this.em.createQuery(query.toString())
				.setParameter(1, (short) 1).setParameter(2, cid)
				.setParameter(3, "customerStatusOut").getResultList();
		return dataList;
	}

	/**
	 * 扫码获取 Customer 的 specService
	 */
	public List<SpecService> getSpecServiceByCID(long cid) {
		List<SpecService> dataList = new ArrayList<SpecService>();
		if (ActionContextHolder.getContext().getUser() != null
				&& ActionContextHolder.getContext().getUser().getId() != null) {
			long uid = ActionContextHolder.getContext().getUser().getId();
			Iterable<NursingPlanDetail> itemList = new ArrayList<NursingPlanDetail>();
			Iterable<CustomerDrugProject> projectList = new ArrayList<CustomerDrugProject>();
			List<CustomerDrugProjectItem> projectListTemp = new ArrayList<CustomerDrugProjectItem>();
			itemList = nursingService.getTimeServiceItemByCID(cid);
			StringBuilder query = new StringBuilder(
					"select u.employee from User u where u.id = ?1 ");// user对应Employee
			List<Employee> employeeList = this.em.createQuery(query.toString())
					.setParameter(1, uid).getResultList();
			int drugProjectFlag = 0;
			// 护理员不能查看用药计划
			if (employeeList != null && employeeList.size() > 0) {
				if (employeeList.get(0).getPosition() != null) {
					if ("postType5".equals(employeeList.get(0).getPosition()
							.getTypecode())) {
						drugProjectFlag = 1;
					}
				}
			}
			if (drugProjectFlag == 0) {
				projectList = getCustomerDrugProjectByCID(cid);
			}
			// 拆分 CustomerDrugProject
			Long idTemp = (long) 1;
			for (CustomerDrugProject project : projectList) {
				if (project != null && project.getUseDrugDate() != null
						&& !"".equals(project.getUseDrugDate())) {
					String[] dates = project.getUseDrugDate().split(",");// 未判断是否为数字
					for (String date : dates) {
						CustomerDrugProjectItem projectTemp = new CustomerDrugProjectItem();
						BeanUtils.copyProperties(project, projectTemp);
						projectTemp.setUseDrugDate(date);
						projectTemp.setProject(project);
						projectTemp.setId(idTemp);
						projectListTemp.add(projectTemp);
						SpecService temp = new SpecService();
						temp.setProject(projectTemp);
						temp.setId(idTemp);
						idTemp++;
						dataList.add(temp);
					}
				}
			}
			for (NursingPlanDetail item : itemList) {
				if (item != null && item.getStartTimeTab() != null
						&& !"".equals(item.getStartTimeTab())) {
					SpecService temp = new SpecService();
					temp.setId(idTemp);
					idTemp++;
					temp.setItem(item);
					dataList.add(temp);
				}
			}
			// 按照时间排序
			Collections.sort(dataList);
		}
		return dataList;
	}

	/**
	 * 获取 user 的 specService 定时任务
	 */
	public List<SpecService> getSpecServiceByUID(long uid) {
		List<SpecService> dataList = new ArrayList<SpecService>();
		Iterable<NursingPlanDetail> itemList = new ArrayList<NursingPlanDetail>();
		Iterable<CustomerDrugProject> projectList = new ArrayList<CustomerDrugProject>();
		List<CustomerDrugProjectItem> projectListTemp = new ArrayList<CustomerDrugProjectItem>();
		// 获取 CustomerDrugProject 与 NursingPlanServiceItem
		// itemList = nursingService.getStaffPlanItem(uid);
		itemList = nursingService.getTimeServiceItemByUID(uid);
		StringBuilder query = new StringBuilder(
				"select u.employee from User u where u.id = ?1 ");// user对应Employee
		List<Employee> employeeList = this.em.createQuery(query.toString())
				.setParameter(1, uid).getResultList();
		int drugProjectFlag = 0;
		// 护理员不能查看用药计划
		if (employeeList != null && employeeList.size() > 0) {
			if (employeeList.get(0).getPosition() != null) {
				if ("postType5".equals(employeeList.get(0).getPosition()
						.getTypecode())) {
					drugProjectFlag = 1;
				}
			}
		}
		if (drugProjectFlag == 0) {
			projectList = getCustomerDrugProjectByUID(uid);
		}
		// 拆分 CustomerDrugProject
		Long idTemp = (long) 1;
		for (CustomerDrugProject project : projectList) {
			if (project != null && project.getUseDrugDate() != null
					&& !"".equals(project.getUseDrugDate())) {
				String[] dates = project.getUseDrugDate().split(",");// 未判断是否为数字
				for (String date : dates) {
					CustomerDrugProjectItem projectTemp = new CustomerDrugProjectItem();
					BeanUtils.copyProperties(project, projectTemp);
					projectTemp.setUseDrugDate(date);
					projectTemp.setProject(project);
					projectTemp.setId(idTemp);
					projectListTemp.add(projectTemp);
					SpecService temp = new SpecService();
					temp.setProject(projectTemp);
					temp.setId(idTemp);
					idTemp++;
					dataList.add(temp);
				}
			}
		}
		for (NursingPlanDetail item : itemList) {
			if (item != null && item.getStartTimeTab() != null
					&& !"".equals(item.getStartTimeTab())) {
				SpecService temp = new SpecService();
				temp.setId(idTemp);
				idTemp++;
				temp.setItem(item);
				dataList.add(temp);
			}
		}
		// 按照时间排序
		Collections.sort(dataList);
		return dataList;
	}

	/**
	 * 获取
	 */
	public List<Customer> getCustomerByContractNOFilterId(String contractNO,
			Long cid) {
		List dataList = null;
		StringBuilder query = new StringBuilder(
				"select c from Customer c where c.id!=?6 and c.contractNO = ?1 and c.delStatus != ?2 and c.tenant.id=?3 "
						+ "and (  c.customerStatus is null or (c.customerStatus.typecode!=?4 and c.customerStatus.typecode!=?5 ) )");
		if (contractNO != null) {
			dataList = this.em
					.createQuery(query.toString())
					.setParameter(1, contractNO)
					.setParameter(2, (short) 1)
					.setParameter(3,
							ActionContextHolder.getContext().getTenantId())
					.setParameter(4, "customerStatusOut")// customerStatusOut退住
					.setParameter(5, "customerStatusSubmit")// customerStatusSubmit已提交
					.setParameter(6, cid).getResultList();
		}
		return dataList;
	}

	/**
	 * 获取
	 */
	public List<Customer> getCustomerByContractNO(String contractNO) {
		List dataList = null;
		StringBuilder query = new StringBuilder(
				"select c from Customer c where c.contractNO = ?1 and c.delStatus != ?2 and c.tenant.id=?3 "
						+ "and (  c.customerStatus is null or (c.customerStatus.typecode!=?4 and c.customerStatus.typecode!=?5 ) )");
		if (contractNO != null) {
			dataList = this.em
					.createQuery(query.toString())
					.setParameter(1, contractNO)
					.setParameter(2, (short) 1)
					.setParameter(3,
							ActionContextHolder.getContext().getTenantId())
					.setParameter(4, "customerStatusOut")// customerStatusOut退住
					.setParameter(5, "customerStatusSubmit")// customerStatusSubmit已提交
					.getResultList();
		}
		return dataList;
	}

	/**
	 * 获取
	 */
	public List<Customer> getCustomerByCardCode(String cardCode) {
		List dataList = null;
		StringBuilder query = new StringBuilder(
				"select c from Customer c where c.cardCode = ?1 and c.delStatus != ?2 and c.tenant.id=?3 "
						+ "and (  c.customerStatus is null or (c.customerStatus.typecode!=?4 and c.customerStatus.typecode!=?5 ) )");
		if (cardCode != null) {
			dataList = this.em
					.createQuery(query.toString())
					.setParameter(1, cardCode)
					.setParameter(2, (short) 1)
					.setParameter(3,
							ActionContextHolder.getContext().getTenantId())
					.setParameter(4, "customerStatusOut")// customerStatusOut退住
					.setParameter(5, "customerStatusSubmit")// customerStatusSubmit已提交
					.getResultList();
		}
		return dataList;
	}

	/**
	 * 获取
	 */
	public List<CustomerServiceItem> getCustomerServiceItemByName(
			String cardCode) {
		StringBuilder query = new StringBuilder(
				"select c from CustomerServiceItem c where c.name = ?1 and c.delStatus != ?2 and c.tenant.id=?3");
		List dataList = this.em
				.createQuery(query.toString())
				.setParameter(1, cardCode)
				.setParameter(2, (short) 1)
				.setParameter(3, ActionContextHolder.getContext().getTenantId())
				.getResultList();
		/*
		 * Customer ct = null; if (dataList.size() > 0) { ct = (Customer)
		 * dataList.get(0); }
		 */
		return dataList;
	}

	/**
	 * 获取
	 */
	public CustomerServiceItem getCustomerServiceItemById(Long id) {
		StringBuilder query = new StringBuilder(
				"select c from CustomerServiceItem c where c.id = ?1 "
				//+ "and c.delStatus != ?2 "
				+ "");
		List dataList = this.em.createQuery(query.toString())
				.setParameter(1, id)
				//.setParameter(2, (short) 1)
				.getResultList();
		CustomerServiceItem ct = null;
		if (dataList.size() > 0) {
			ct = (CustomerServiceItem) dataList.get(0);
		}
		return ct;
	}

	/**
	 * 获取
	 */
	public EvaluateModel getEvaluateModelByTitleFilterId(String title, Long id) {
		StringBuilder query = new StringBuilder(
				"select c from EvaluateModel c where c.title = ?1 and c.delStatus != ?2 and c.tenant.id=?3 and c.id!=?4");
		List dataList = this.em
				.createQuery(query.toString())
				.setParameter(1, title)
				.setParameter(2, (short) 1)
				.setParameter(3, ActionContextHolder.getContext().getTenantId())
				.setParameter(4, id).getResultList();
		EvaluateModel ct = null;
		if (dataList.size() > 0) {
			ct = (EvaluateModel) dataList.get(0);
		}

		return ct;
	}

	/**
	 * 获取
	 */
	public EvaluateModel getEvaluateModelByTitle(String title) {
		StringBuilder query = new StringBuilder(
				"select c from EvaluateModel c where c.title = ?1 and c.delStatus != ?2 and c.tenant.id=?3 ");
		List dataList = this.em
				.createQuery(query.toString())
				.setParameter(1, title)
				.setParameter(2, (short) 1)
				.setParameter(3, ActionContextHolder.getContext().getTenantId())
				.getResultList();

		EvaluateModel ct = null;
		if (dataList.size() > 0) {
			ct = (EvaluateModel) dataList.get(0);
		}

		return ct;
	}

	/**
	 * 获取
	 */
	public EvaluateModel getEvaluateModelById(Long id) {
		StringBuilder query = new StringBuilder(
				"select c from EvaluateModel c where c.id = ?1 and c.delStatus != ?2 ");
		List dataList = this.em.createQuery(query.toString())
				.setParameter(1, id).setParameter(2, (short) 1).getResultList();
		EvaluateModel ct = null;
		if (dataList.size() > 0) {
			ct = (EvaluateModel) dataList.get(0);
		}
		return ct;
	}

	/**
	 * 获取护理组对应laoren
	 */
	public List<Customer> getCustomerByGroup(NurseGroup group) {
		if (group == null) {
			return null;
		}
		StringBuilder query = new StringBuilder("select m from Customer m where m.delStatus != ?1 "
				+ "and m.bed in ( select  c.bed from BedNurseGroup c where c.group.id=?2 and c.delStatus != ?1  and  c.tenant.id=?3  and (c.bed.status.typecode=?4 or c.bed.status.typecode=?5 ))");
		List dataList = this.em.createQuery(query.toString()).setParameter(1, (short) 1).setParameter(2, group.getId())
				.setParameter(3, ActionContextHolder.getContext().getTenantId())
				.setParameter(4, CommonConstants.DICTTYPE.BED_STATUS_3.label())
				.setParameter(5, CommonConstants.DICTTYPE.BED_STATUS_2.label()).getResultList();
		return dataList;
	}

	/**
	 * 获取
	 */
	public Device getDeviceBySeq(Device data) {
		logger.debug("add  device judge");
		StringBuilder query = new StringBuilder(
				"select c from Device c where c.seq = ?1 and c.delStatus != ?2 and c.type.codeInfo=?3 and c.deviceType.typecode=?4 ");
		List dataList = this.em.createQuery(query.toString())
				.setParameter(1, data.getSeq()).setParameter(2, (short) 1)
				.setParameter(3, data.getType().getCodeInfo())
				.setParameter(4, data.getDeviceType().getTypecode())
				.getResultList();
		logger.debug("add  device judge  size" + dataList.size());
		Device ct = null;
		if (dataList.size() > 0) {
			ct = (Device) dataList.get(0);
		}

		return ct;
	}

	/**
	 * 获取
	 */
	public Device getDeviceBySeqFilterId(Device data) {
		StringBuilder query = new StringBuilder(
				"select c from Device c where c.seq = ?1 and c.delStatus != ?2   and c.id!=?3 and c.type.codeInfo=?4 and c.deviceType.typecode=?5 ");
		List dataList = this.em.createQuery(query.toString())
				.setParameter(1, data.getSeq()).setParameter(2, (short) 1)
				.setParameter(3, data.getId())
				.setParameter(4, data.getType().getCodeInfo())
				.setParameter(5, data.getDeviceType().getTypecode())
				.getResultList();
		Device ct = null;
		if (dataList.size() > 0) {
			ct = (Device) dataList.get(0);
		}
		return ct;
	}

	/**
	 * 获取客户设备
	 */
	public List<Device> getCustomerDevices(Customer customer) {
		StringBuilder query = new StringBuilder(
				"select  c.device from CustomerDevice c where c.delStatus != ?1 and  c.customer.id=?2 ");
		List dataList = this.em.createQuery(query.toString())
				.setParameter(1, (short) 1).setParameter(2, customer.getId())
				.getResultList();
		return dataList;
	}

	/**
	 * 获取客户设备
	 */
	public CustomerDevice getCustomerDeviceById(CustomerDevice data) {
		StringBuilder query = new StringBuilder(
				"select  c from CustomerDevice c where   c.id=? ");
		CustomerDevice device = (CustomerDevice) this.em
				.createQuery(query.toString()).setParameter(1, data.getId())
				.getSingleResult();
		return device;
	}

	/**
	 * 获取客户设备
	 */
	public CustomerDevice getCustomerDeviceByDeviceType(CustomerDevice data) {
		StringBuilder query = new StringBuilder(
				"select  c from CustomerDevice c where   c.delStatus!=1  and c.customer.id=?2 and c.device.type.id=?3 and c.device.deviceType.id=?4 ");
		List<CustomerDevice> deviceList = this.em.createQuery(query.toString())
				.setParameter(2, data.getCustomer().getId())
				.setParameter(3, data.getDevice().getType().getId())
				.setParameter(4, data.getDevice().getDeviceType().getId())
				.getResultList();
		CustomerDevice cDevice = null;
		if (deviceList.size() > 0) {
			cDevice = deviceList.get(0);
		}
		return cDevice;
	}

	/**
	 * 更改customer状态
	 */
	public void changeCustomerStauts(Customer customer, Dicttype status) {
		customer.setCustomerStatus(status);
		dslJpaService.setEntityClass(Customer.class);
		dslJpaService.update(customer);
	}

	/**
	 * 获取
	 */
	public CustomerServerChange getCustomerServerChange(
			CustomerServerChange record) {
		Long id = record.getId();
		StringBuilder query = new StringBuilder(
				"select c from CustomerServerChange c where c.id = ?1 ");
		CustomerServerChange ct = (CustomerServerChange) this.em
				.createQuery(query.toString()).setParameter(1, id)
				.getSingleResult();
		return ct;
	}

	/**
	 * create businessflow 验证床位是否可用
	 */
	public int operateBusinessFlowFlag(CustomerBusinessFlow record) {
		String flowStatus = record.getStatus().getTypecode();
		Bed bedNew = null;
		Bed bedOld = null;
		if (record.getId() == null) {// 新建flow验证
			if ("consultStatus3".equals(flowStatus)) {
				bedNew = workPlaceService.getBedById(record.getOrderBed()
						.getId());// 预定
			}
			if ("consultStatus4".equals(flowStatus)
					|| "consultStatus5".equals(flowStatus)) {
				bedNew = workPlaceService.getBedById(record.getCheckInBed()
						.getId());// 直接入住
									// 直接试住
			}
			if (bedNew.getStatus() == null
					|| CommonConstants.DICTTYPE.BED_STATUS_1.label().equals(
							bedNew.getStatus().getTypecode())) {
				return 1;
			} else {
				return 0; // 床位已占用
			}
		} else {// 修改flow验证
			CustomerBusinessFlow ctTemp = this.getCustomerBusinessFlow(record);
			if ("consultStatus3".equals(ctTemp.getStatus().getTypecode())
					&& "consultStatus4"
							.equals(record.getStatus().getTypecode()) // 预定转试住
			) {
				bedOld = ctTemp.getOrderBed();
				bedNew = record.getCheckInBed();
				// bedNew = record.getExperienceBed();
			}
			if ("consultStatus3".equals(ctTemp.getStatus().getTypecode())
					&& "consultStatus5"
							.equals(record.getStatus().getTypecode()) // 预定转入住
			) {
				bedOld = ctTemp.getOrderBed();
				bedNew = record.getCheckInBed();
			}
			if ("consultStatus4".equals(ctTemp.getStatus().getTypecode())
					&& "consultStatus5"
							.equals(record.getStatus().getTypecode()) // 试住转入住
			) {
				bedOld = ctTemp.getCheckInBed();
				// bedOld = ctTemp.getExperienceBed();
				bedNew = record.getCheckInBed();
			}
			if (bedOld.getId().equals(bedNew.getId())) {// 床位未发生变化
				return 1;
			} else {
				bedNew = workPlaceService.getBedById(bedNew.getId());
				if (bedNew.getStatus() == null
						|| CommonConstants.DICTTYPE.BED_STATUS_1.label()
								.equals(bedNew.getStatus().getTypecode())) {
					return 1;
				} else {
					return 0; // 床位已占用
				}
			}
		}
	}

	// 预定 直接试住 入住 删除新建相应的老人 以及账户 充值记录
	@Transactional
	public void deleteCustomerOnOperateFLow(Customer customer) {
		StringBuilder query = new StringBuilder(
				"update Customer u set u.delStatus = ?1 , u.updateTime = ?2  where u.id = ?3");
		// 修改用户状态
		this.em.createQuery(query.toString()).setParameter(1, (short) 1)
				.setParameter(3, customer.getId())
				.setParameter(2, CommonUtil.getCurrTimes()).executeUpdate();
		query.delete(0, query.length());
		query.append("update TradeAccount u set u.delStatus = ?1 , u.lastUpdateDateTime = ?2  where u.customer.id = ?3");
		// 修改账户状态
		this.em.createQuery(query.toString()).setParameter(1, (short) 1)
				.setParameter(3, customer.getId())
				.setParameter(2, CommonUtil.getCurrTimes()).executeUpdate();
		query.delete(0, query.length());
		query.append("update RechargeRecord u set u.delStatus = ?1 , u.lastUpdateDateTime = ?2  where u.rechargeAccount.customer.id = ?3");
		// 修改账户充值记录状态
		// this.em.createQuery(query.toString()).setParameter(1, (short) 1)
		// .setParameter(3, customer.getId())
		// .setParameter(2, CommonUtil.getCurrTimes()).executeUpdate();
		// 房间设为空闲
		if (customer.getBed() == null) {
			customer = getCustomer(customer);
		}
		workPlaceService.changeDedStauts(customer.getBed(), commonService
				.getDicttype(CommonConstants.DICTTYPE.BED_STATUS_1.label()));
	}

	// 新建Customer后 非直接生成 （生成账户以及充值记录） 直接生成客户状态为 直接入住 不生成账户
	@Transactional
	public void operateCreateCustomer(Customer customer) {
		Dicttype ensureAccount = commonService
				.getDicttype(CommonConstants.DICTTYPE.ACCOUNT_TYPE_1.label());
		Dicttype EAccount = commonService
				.getDicttype(CommonConstants.DICTTYPE.ACCOUNT_TYPE_2.label());
		if (customer.getQrCodeUrl() == null
				|| "".equals(customer.getQrCodeUrl())) {
			customer.setQrCodeUrl(GenerateQrCodeUtil.generateQrcode("tnbId:"
					+ customer.getId().toString())); // 生成客户ID微信二维码
			dslJpaService.setEntityClass(Customer.class);
			dslJpaService.update(customer);
		}
		if (customer.getAddRemark() == null
				|| "".equals(customer.getAddRemark())
				|| "normal".equals(customer.getAddRemark())) {// 非直接生成（生成账户以及充值记录）
			if (customer.getActualDeposit() != null
					&& !"".equals(customer.getActualDeposit())) {
				// 生成客户的电子账户和保证金账户
				TradeAccount accountE = this.createAccount(customer, EAccount,
						0.0);
				TradeAccount accountSure = this.createAccount(customer,
						ensureAccount,
						Double.parseDouble(customer.getActualDeposit()));
				// 充值记录
				TradeAccount orgAccount = accountService
						.findOrgAccountByOrg(ActionContextHolder.getContext()
								.getUser().getOrg().getId());
				RechargeRecord record = new RechargeRecord();
				record.setBalance(Double.parseDouble(customer
						.getActualDeposit()));
				record.setCreateDateTime(CommonUtil.getCurrTimes());
				record.setDelStatus((short) 0);
				record.setMoney(Double.parseDouble(customer.getActualDeposit()));
				record.setRechargeAccount(accountSure);
				record.setGatherAccount(orgAccount);
				record.setChannel(commonService.getDicttype("rechargeChannel1"));
				accountService.createRechargeRecord(record);
			}
		} else if ("directCreate".equals(customer.getAddRemark())) {// 直接新增 （ ）

		}

	}

	// 根据flow数据生成customer
	public Customer copyCusomerDataFromBusinessFlow(CustomerBusinessFlow flow,
			Customer customer) {
		try {
			commonService.copy(flow, customer);
		} catch (Exception e) {
			logger.debug("copyCusomerDataFromBusinessFlow error :" + e);
		}
		customer.setEducationLevel(flow.getCustomerEducation());
		customer.setOldManType(flow.getCustomerOldManType());
		customer.setMedicalInsuranceCategory(flow
				.getCustomerMedicalInsuranceCategory());
		customer.setContractNO(flow.getInContractNO());// 合同编号
		customer.setContractStartDate(flow.getCheckInStartTime());
		customer.setContractEndDate(flow.getCheckInEndTime());// 合同时间
		customer.setCheckInDate(flow.getCheckInStartTime());// 入住时间
		customer.setDiningStandard(flow.getDiningStandard());// 餐饮标准
		customer.setBed(flow.getCheckInBed());// 床位
		customer.setActualPrice(flow.getCheckInPrice());// 实际价格
		customer.setActualDeposit(flow.getOrderMoney());// 保证金
		if (customer.getHeadImg() == null || "".equals(customer.getHeadImg())) {
			customer.setHeadImg(flow.getHeadImg());
		}
		if (customer.getTown() == null) {
			customer.setTown(flow.getTown());
		}
		if (StringUtils.isNotBlank(flow.getCustomerBrith())) {
			customer.setBirthday(Integer.parseInt(flow.getCustomerBrith()));// 生日
		}
		if (flow.getDiningStandardPrice() != null) {
			customer.setActualDiningPrice(flow.getDiningStandardPrice()
					.toString());
		}
		if (flow.getBedPrice() != null) {
			customer.setActualBedPrice(flow.getBedPrice().toString());
		}
		customer.setCardCode(flow.getCustomerCardCode());// 身份证号
		customer.setName(flow.getCustomerName());// name
		customer.setPhone(flow.getCustomerTel());
		customer.setSelfCareAbility(flow.getCustomerSelfCareAbility());
		customer.setSex(flow.getCustomerGender());
		customer.setAge(flow.getCustomerAge());
		return customer;
	}

	
	/**
	 *   将Customer相关信息复制到Flow中
	 *   @author huibati
	 *   @param
	 *   2017年9月12日
	 */
	public void copyFlowDataFromCustomer(Customer customer) {
		CustomerBusinessFlow flow;
		StringBuilder queryFlow = new StringBuilder(
				"select h from CustomerBusinessFlow h where h.delStatus != ?1 and h.customer.id=?2 and h.leaveStatus is null");
		List<CustomerBusinessFlow> flowList = this.em
				.createQuery(queryFlow.toString()).setParameter(1, (short) 1)
				.setParameter(2, customer.getId()).getResultList();
		if(flowList==null||flowList.size()==0){
			return ;
		}else{
			flow=flowList.get(0);	
		}
		flow.setCustomerName(customer.getName());
		flow.setCustomerCardCode(customer.getCardCode());// 身份证号
		flow.setCustomerGender(customer.getSex());
		flow.setCustomerEducation(customer.getEducationLevel());
		flow.setCustomerAge(customer.getAge());
		flow.setCustomerOldManType(customer.getOldManType());
		flow.setCustomerMedicalInsuranceCategory(customer.getMedicalInsuranceCategory());
		flow.setHeadImg(customer.getHeadImg());
		flow.setTown(customer.getTown());
		flow.setCustomerBrith(customer.getBirthday().toString());// 生日
		flow.setCustomerTel(customer.getPhone());
		flow.setCustomerSelfCareAbility(customer.getSelfCareAbility());
		flow.setCustomerGender(customer.getSex());
		flow.setCustomerAddr(customer.getAddress());
		flow.setCustomerPS(customer.getCustomerPS());
		flow.setCustomerNationality(customer.getNationality());
		flow.setCustomerNative(customer.getCustomerNative());
        dslJpaService.setEntityClass(CustomerBusinessFlow.class);
        dslJpaService.update(flow);

	}
	
	/**
	 * 新建customer
	 */
	public Customer createCustomer(Customer customer) {
		dslJpaService.setEntityClass(Customer.class);
		dslJpaService.create(customer);
		return customer;
	}

	// 根据nursinglevel 建立 nursingproject 将level对应的serviceItem copy到project中
	@Transactional
	public void createCustomerProjectByNursingLevel(Customer customer,
			NursingLevel level, Double actualProjectPrice) {
		NursingProject project = new NursingProject();
		project.setCustomer(customer);
		if (actualProjectPrice != null) {
			project.setPrice(actualProjectPrice);
		} else {
			project.setPrice(Double.parseDouble(level.getPrice()));
		}
		project.setLevel(level);
		project.setName(customer.getName() + "的护理方案");
		project.setCreateUser(ActionContextHolder.getContext().getUser());
		dslJpaService.setEntityClass(NursingProject.class);
		dslJpaService.create(project);
		StringBuilder queryItem = new StringBuilder(
				"select h from NursingLevelServiceItem h where h.delStatus != ?1 and h.level.id=?2 ");
		List<NursingLevelServiceItem> itemList = this.em
				.createQuery(queryItem.toString()).setParameter(1, (short) 1)
				.setParameter(2, level.getId()).getResultList();
		if (itemList != null && itemList.size() > 0) {
			List<NursingProjectServiceItem> dataList = new ArrayList<>();
			for (NursingLevelServiceItem levelItem : itemList) {
				if (levelItem != null) {
					NursingProjectServiceItem projectServiceItem = new NursingProjectServiceItem();
					projectServiceItem.setProject(project);
					projectServiceItem.setFrequency(levelItem.getFrequency());
					projectServiceItem.setItem(levelItem.getItem());
					projectServiceItem.setPeriod(levelItem.getPeriod());
					projectServiceItem.setPrice(levelItem.getPrice());
					projectServiceItem.setServiceTime(levelItem
							.getServiceTime());
					projectServiceItem.setDelStatus((short) 0);
					projectServiceItem.setTenant(customer.getTenant());
					dataList.add(projectServiceItem);
				}
			}
			if (dataList.size() > 0) {
				commonService.batchInsert(dataList);
			}
		}
	}

	// 通过customer 修改相应flow 状态
	public void updateBusinessFlowStatusByCustomer(Customer customer,
			String statusCode) {
		StringBuilder queryFlow = new StringBuilder(
				"select c from CustomerBusinessFlow c where c.delStatus != ?1 "
						+ " and c.customer.id=?2 "
						+ " and (c.status.typecode=?3 or c.status.typecode=?4  ) ");
		List<CustomerBusinessFlow> flowList = this.em
				.createQuery(queryFlow.toString()).setParameter(1, (short) 1)
				.setParameter(2, customer.getId())
				.setParameter(3, "consultStatus3")
				.setParameter(4, "consultStatus4").getResultList();
		if (flowList != null && flowList.size() > 0) {
			if ("consultStatus3".equals(flowList.get(0).getStatus()
					.getTypecode())) {
				statusCode = "";// 试住 提交退住
			}
			if ("consultStatus4".equals(flowList.get(0).getStatus()
					.getTypecode())) {
				statusCode = "";// 入住 提交退住
			}
			flowList.get(0).setStatus(commonService.getDicttype(statusCode));
			dslJpaService.setEntityClass(CustomerBusinessFlow.class);
			dslJpaService.update(flowList.get(0));
		}

	}

	/**
	 * 居家添加customer是需要生成相应的user
	 *
	 * @author ytche
	 * @param customer
	 * @date 2017年5月10日 下午6:23:12
	 */
	@SuppressWarnings("unchecked")
	@Transactional
	public void createUser(Customer customer) {
		User user = new User();
		BeanUtils.copyProperties(customer, user, "id");
		List<User> users = this.userService.findUsersByLoginName(customer
				.getPhone());
		String loginName = customer.getPhone();
		if (users != null && users.size() > 0) {
			loginName += users.size();
		}
		user.setLoginName(loginName);
		user.setPasscode(CommonUtil
				.stringMD5(ICommonConstants.DEFALUT_PASSCODE));
		user.setPassword(user.getPasscode());
		user.setStaffStatus(this.dicttypeService
				.findById(ICommonConstants.DIC_ID_STAFF_STATUS_ON));
		user.setRole(this.roleService.getRoleByTenantAndCode(customer
				.getTenant().getId(), CommonConstants.ROLE_CODE.WECHAT
				.getCode()));
		dslJpaService.setEntityClass(User.class);
		user = (User) dslJpaService.create(user);
		StaffCustomer staffCustomer = new StaffCustomer();
		staffCustomer.setStaff(user);
		staffCustomer.setCustomer(customer);
		dslJpaService.setEntityClass(StaffCustomer.class);
		dslJpaService.create(staffCustomer);
	}

	/**
	 * 居家端修改会员名字时同步修改用户名
	 *
	 * @author ytche
	 * @param customer
	 * @date 2017年6月5日 下午6:11:38
	 */
	@Transactional
	@SuppressWarnings("unchecked")
	public void updateUser(Customer customer) {
		this.dslJpaService.setEntityClass(Customer.class);
		customer = (Customer) this.dslJpaService.findById(customer.getId());
		User user = customer.getStaffs().get(0);
		user.setName(customer.getName());
		this.dslJpaService.setEntityClass(User.class);
		this.dslJpaService.update(user);
	}

	/**
	 * 获取employee照料老人
	 */
	public Iterable<Customer> getCustomerByEID(long employeeId) {
		return this.getCustomerByEID(employeeId, true);
	}

	/**
	 * 获取employee照料老人
	 *
	 * @author ytche
	 * @param employeeId
	 * @param withLeave
	 *            true包含请假老人false不包含请假老人
	 * @return
	 * @date 2017年8月23日 下午4:38:04
	 */
	public List<Customer> getCustomerByEID(long employeeId, boolean withLeave) {
		StringBuilder queryCustomer = new StringBuilder(
				"select c from Customer c where c.delStatus != 1 and  c.customerStatus is not null and c.customerStatus.typecode!=?3 and c.bed in "
						+ "( select b from Bed b where b.delStatus != ?1 "
						+ "and b in "
						+ "  ( select n.bed from BedNurseGroup n where n.delStatus != ?1 "
						+ "and n.group in ( select c.group from EmployeeNursingGroup c where c.delStatus != 1 and c.employee.id = ?2 ) "
						+ "  )" + ")");
		if (!withLeave) {
			queryCustomer
					.append(" and c not in ( select cl.customer from CustomerLeave cl where cl.delStatus != 1 and cl.tenant.id=c.tenant.id and cl.status=1)");
		}
		List<Customer> customerList = this.em
				.createQuery(queryCustomer.toString())
				.setParameter(1, (short) 1).setParameter(2, employeeId)
				.setParameter(3, "customerStatusOut").getResultList();
		return customerList;

	}

	/**
	 * 校验身份中重复
	 *
	 * @author ytche
	 * @param cardCode
	 * @return
	 * @date 2017年6月7日 上午10:31:43
	 */
	@SuppressWarnings("unchecked")
	public List<Customer> checkCardCode(String cardCode) {
		String queryStr = "From Customer c where c.cardCode = ?1 and c.delStatus = 0";
		return this.em.createQuery(queryStr).setParameter(1, cardCode)
				.getResultList();
	}

	/**
	 * 手机端初始化是获取老人列表
	 *
	 * @author ytche
	 * @param userId
	 * @return
	 * @date 2017年7月14日 下午5:37:52
	 */
	public List<Customer> getCustomerForMobile(Long userId) {
		String queryCustomer = "select c from Customer c where c.delStatus != 1 and  c.customerStatus is not null"
				+ " and (c.customerStatus.typecode=?1 or c.customerStatus.typecode=?2)"
				+ " and c.bed in ( select b from Bed b where b.delStatus != 1 "
				+ " and b in( select n.bed from BedNurseGroup n where n.delStatus != 1"
				+ " and n.group in( select c.group from EmployeeNursingGroup c where c.delStatus != 1 "
				+ " and c.employee in (select u.employee from User u where u.id = ?3 )) ))";

		return this.em.createQuery(queryCustomer)
				.setParameter(1, "customerStatusIn")
				.setParameter(2, "customerStatusTry").setParameter(3, userId)
				.getResultList();
	}

	/**
	 * 获取用户相关的customer
	 *
	 * @author ytche
	 * @param user
	 * @return
	 * @date 2017年9月4日 下午1:51:51
	 */
	@SuppressWarnings("unchecked")
	public List<Customer> findByUser(User user) {
		if (user == null) {
			return null;
		}
		String queryStr = "select c from Customer as c join c.staffs s where s.id=:userId ";
		return this.em.createQuery(queryStr)
				.setParameter("userId", user.getId()).getResultList();
	}
	
	/**
	 *   获取老人列表判断老人是否有年度护理计划单周护理计划以及护理方案
	 *   @author huibati
	 *   @param
	 *   2017年9月9日
	 */
	public Iterable<Customer> getCustomerWithFlag(Iterable<Customer> customerList) {
		//试住入住老人列表
//		StringBuilder queryCustomer = new StringBuilder(
//				"select c from Customer c where c.delStatus != ?1 and c.tenant.id=?2 and "
//						+ " ( c.customerStatus.typecode =?3 or c.customerStatus.typecode =?4  )");
//		List<Customer> customerList = this.em
//				.createQuery(queryCustomer.toString())
//				.setParameter(1, (short) 1)
//				.setParameter(2, ActionContextHolder.getContext().getTenantId())
//				.setParameter(3, CommonConstants.DICTTYPE.CUSTOMER_STATUS_TRY.label())
//				.setParameter(4, CommonConstants.DICTTYPE.CUSTOMER_STATUS_IN.label())
//				.getResultList();
		//Map<Long, Customer> dataMap= (Map<Long, Customer>) customerList.stream().collect(Collectors.toMap(Customer::getId, Function.identity(), (key1, key2) -> key2));
		//拥有护理方案的老人
		StringBuilder queryProject = new StringBuilder(
				"select p.customer from NursingProject p where p.delStatus != ?1 and p.tenant.id=?2");
		List projectList = this.em
				.createQuery(queryProject.toString())
				.setParameter(1, (short) 1)
				.setParameter(2, ActionContextHolder.getContext().getTenantId())
				.getResultList();
		Map<Long, Customer> projectMap= (Map<Long, Customer>) projectList.stream().collect(Collectors.toMap(Customer::getId, Function.identity(), (key1, key2) -> key2));
		
		//拥有护理计划模版的老人
		StringBuilder queryModel = new StringBuilder(
				"select p.customer from NursingPlanServiceItem p where p.delStatus != ?1 and p.tenant.id=?2");
		List modelList = this.em
				.createQuery(queryModel.toString())
				.setParameter(1, (short) 1)
				.setParameter(2, ActionContextHolder.getContext().getTenantId())
				.getResultList();
		Map<Long, Customer> modelMap= (Map<Long, Customer>) modelList.stream().collect(Collectors.toMap(Customer::getId, Function.identity(), (key1, key2) -> key2));
		
		//拥有当周护理计划的老人
		Date date = new Date();
		int year = date.getYear() + 1900;
		int weekIndex = CommonUtil.getWeekIndexFromSun(date);//当前所在周
		StringBuilder detailModel = new StringBuilder(
				"select  p.customer from NursingPlanDetail p where p.delStatus != ?1 and p.tenant.id=?2 and p.yearTab=?3 and p.weekIndex=?4  ");
		List detailList = this.em.createQuery(detailModel.toString()).setParameter(1, (short) 1)
				.setParameter(2, ActionContextHolder.getContext().getTenantId())
				.setParameter(3, year)
				.setParameter(4, weekIndex)
				.getResultList();
		Map<Long, Customer> detailMap = (Map<Long, Customer>) detailList.stream()
				.collect(Collectors.toMap(Customer::getId, Function.identity(), (key1, key2) -> key2));

		for(Customer data:customerList){
			String flagRemark="[{";
			if(projectMap.containsKey(data.getId())){
				flagRemark+="\"project\":\"true\"";
			}else{
				flagRemark+="\"project\":\"false\"";
			}
			if(modelMap.containsKey(data.getId())){
				flagRemark+=",\"model\":\"true\"";
			}else{
				flagRemark+=",\"model\":\"false\"";
			}
			if(detailMap.containsKey(data.getId())){
				flagRemark+=",\"detail\":\"true\"";
			}else{
				flagRemark+=",\"detail\":\"false\"";
			}
			flagRemark+="}]";
			data.setFlagRemark(flagRemark);
		}
		
		return customerList;
	}
	
	
	/**
	 * 获取某租户下处于试住入住的老人
	 * 
	 * @author huibati
	 * @param 2017年9月11日
	 */
	public List<Customer> getCustomerInOrTry(Long tenantId) {
		List<Customer> customerList = null;
		StringBuilder sql = new StringBuilder(
				"select a from Customer a where a.delStatus != ?1 and ( a.customerStatus.typecode=?2 or a.customerStatus.typecode=?3 ) and a.tenant.id=?4");
		customerList = this.em.createQuery(sql.toString()).setParameter(1, (short) 1)
				.setParameter(2, CommonConstants.DICTTYPE.CUSTOMER_STATUS_IN.label())
				.setParameter(3, CommonConstants.DICTTYPE.CUSTOMER_STATUS_TRY.label())
				.setParameter(4, tenantId)
				.getResultList();
		return customerList;
	}
	
	/**
	 * 获取某租户下当天请假中以及退住的老人
	 * 
	 * @author huibati
	 * @param 2017年9月11日
	 */
	public List<Customer> getCustomerOutOrLeaving(Long tenantId,Integer dateTime) {
		List<Customer> customerOutList = new ArrayList<>();
		List<Customer> customerLeaveList = new ArrayList<>();
		Integer timeStart=0;
		Integer timeEnd=0;
		try {
			timeStart = CommonUtil
					.strToIntegerTime(CommonUtil.integetTimeForString(dateTime).substring(0, 10) + " 00:00:00");
			timeEnd = CommonUtil
					.strToIntegerTime(CommonUtil.integetTimeForString(dateTime).substring(0, 10) + " 23:59:59");
		} catch (ParseException e) {
			logger.debug("date error " + e);
		}
		StringBuilder sql = new StringBuilder(
				"  select a.customer from CustomerBusinessFlow a where a.delStatus != ?1 and a.leaveDate >= ?2 and a.leaveDate <= ?3 and a.tenant.id=?4");
		customerOutList = this.em.createQuery(sql.toString())
				.setParameter(1, (short) 1)
				.setParameter(2, timeStart)
				.setParameter(3, timeEnd)
				.setParameter(4, tenantId)
				.getResultList();
		StringBuilder sqlL = new StringBuilder(
				"  select c.customer from CustomerLeave c where c.delStatus != ?1 and c.status =?2 and c.tenant.id=?3  ");
		customerLeaveList = this.em.createQuery(sqlL.toString()).setParameter(1, (short) 1)
				.setParameter(2, LeaveStatus.LEAVING.getValue()).setParameter(3, tenantId).getResultList();
		customerOutList.removeAll(customerLeaveList);
		customerOutList.addAll(customerLeaveList);
		return customerOutList;
	}
	
	/**
	 * 获取某租户下某天入住老人
	 * 
	 * @author huibati
	 * @param 2017年9月11日
	 */
	public List<Customer> getCustomerNewIn(Long tenantId,Integer dateTime ) {
		List<Customer> customerList = null;
		Integer timeStart=0;
		Integer timeEnd=0;
		try {
			timeStart = CommonUtil
					.strToIntegerTime(CommonUtil.integetTimeForString(dateTime).substring(0, 10) + " 00:00:00");
			timeEnd = CommonUtil
					.strToIntegerTime(CommonUtil.integetTimeForString(dateTime).substring(0, 10) + " 23:59:59");
		} catch (ParseException e) {
			logger.debug("date error " + e);
		}
		StringBuilder sql = new StringBuilder(
				"select a.customer from CustomerBusinessFlow a where a.delStatus != ?1 and"
				+ "( ( a.experienceStartTime>=?2 and a.experienceStartTime<=?3 ) or ( a.experienceStartTime is null  and  a.checkInStartTime>=?2 and a.checkInStartTime<=?3  ) )"
				+ "and a.tenant.id=?4");
		customerList = this.em.createQuery(sql.toString()).setParameter(1, (short) 1)
				.setParameter(2, timeStart)
				.setParameter(3, timeEnd)
				.setParameter(4, tenantId)
				.getResultList();
		return customerList;
	}
}